#!/bin/bash

set -o errexit

test_dir=$(realpath $(dirname $0))
. ${test_dir}/../functions

set_debug

is_password_updated() {
	local username=$1
	local uri=$2
	run_mysql "SELECT User_attributes FROM mysql.user WHERE user='${username}'" "${uri}" | grep additional_password
}

is_old_password_discarded() {
	local username=$1
	local uri=$2
	run_mysql "SELECT User_attributes FROM mysql.user WHERE user='${username}'" "${uri}" | grep NULL
}

wait_for_password_propagation() {
	local secret=$1
	local user=$2
	local max_retry="${3:-240}"
	local root_pass=$(getSecretData "${secret}" "root")

	if [[ $IMAGE_PXC =~ 5\.7 ]]; then
		echo "Skipping dual password feature doesn't work for 5.7. PXC 5.7 doesn't support it!"
		return
	fi
	retry=0
	until is_password_updated "${user}" "-h ${cluster}-pxc -uroot -p'${root_pass}'"; do
		echo "waiting for password update"
		sleep 1
		let retry+=1
		if [[ $retry -ge $max_retry ]]; then
			echo max retry count $retry reached. something went wrong with operator or kubernetes cluster
			exit 1
		fi
	done

	retry=0
	until is_old_password_discarded "${user}" "-h ${cluster}-pxc -uroot -p'${root_pass}'"; do
		echo "waiting for password propagation"
		sleep 1
		let retry+=1
		if [[ $retry -ge $max_retry ]]; then
			echo max retry count $retry reached. something went wrong with operator or kubernetes cluster
			exit 1
		fi
	done
}

create_infra $namespace

desc 'create PXC cluster'

newpass="test-password"
newpassencrypted=$(echo -n "$newpass" | base64)

cluster="some-name"
spinup_pxc "$cluster" "$conf_dir/$cluster.yml"

desc 'test root'
patch_secret "my-cluster-secrets" "root" "$newpassencrypted"
sleep 15
compare_mysql_cmd "select-4" "SHOW TABLES;" "-h $cluster-proxysql -uroot -p'$newpass'"

desc 'test proxyadmin'
kubectl_bin patch pxc some-name --type=merge -p="{\"spec\":{\"proxysql\":{\"size\":3}}}"
sleep 15
wait_cluster_consistency "$cluster" 3 3
patch_secret "my-cluster-secrets" "proxyadmin" "$newpassencrypted"
sleep 15
wait_cluster_consistency "$cluster" 3 3
compare_mysql_cmd_local "select-2" "SHOW TABLES;" "-h127.0.0.1 -P6032 -uproxyadmin -p'$newpass'" "$cluster-proxysql-0" "" 'proxysql'
compare_mysql_cmd_local "select-2" "SHOW TABLES;" "-h127.0.0.1 -P6032 -uproxyadmin -p'$newpass'" "$cluster-proxysql-1" "" 'proxysql'
compare_mysql_cmd_local "select-2" "SHOW TABLES;" "-h127.0.0.1 -P6032 -uproxyadmin -p'$newpass'" "$cluster-proxysql-2" "" 'proxysql'

desc 'test xtrabackup'
kubectl_bin patch pxc some-name --type=merge -p="{\"spec\":{\"proxysql\":{\"size\":2}}}"
patch_secret "my-cluster-secrets" "xtrabackup" "$newpassencrypted"
sleep 15
wait_cluster_consistency "$cluster" 3 2
compare_mysql_cmd_local "select-3" "SHOW DATABASES;" "-h 127.0.0.1 -uxtrabackup -p'$newpass'" "$cluster-pxc-0" "" 'pxc'

desc 'test clustercheck'
patch_secret "my-cluster-secrets" "clustercheck" "$newpassencrypted"
sleep 15
wait_cluster_consistency "$cluster" 3 2
compare_mysql_cmd_local "select-5" "SHOW DATABASES;" "-h 127.0.0.1 -uclustercheck -p'$newpass'" "$cluster-pxc-0" "" 'pxc'

desc 'test monitor'
patch_secret "my-cluster-secrets" "monitor" "$newpassencrypted"
wait_for_password_propagation "my-cluster-secrets" "monitor"
wait_cluster_consistency "$cluster" 3 2
sleep 10 # give some time for proxy-admin --syncusers
compare_mysql_cmd "select-4" "SHOW TABLES;" "-h $cluster-proxysql -umonitor -p'$newpass'"

desc 'test operator'
patch_secret "my-cluster-secrets" "operator" "$newpassencrypted"
sleep 15
wait_cluster_consistency "$cluster" 3 2
sleep 10 # give some time for proxy-admin --syncusers
compare_mysql_cmd "select-4" "SHOW TABLES;" "-h $cluster-proxysql -uoperator -p'$newpass'"

desc 'change secret name'
kubectl_bin patch pxc $cluster --type merge --patch '{"spec": {"secretsName":"my-cluster-secrets-2"}}'
sleep 30
wait_cluster_consistency "$cluster" 3 2

desc 'test new operator'
newpass="test-password2"
newpassencrypted=$(echo -n "$newpass" | base64)
patch_secret "my-cluster-secrets-2" "operator" "$newpassencrypted"
sleep 15
wait_cluster_consistency "$cluster" 3 2

sleep 20 # give some time for proxy-admin --syncusers

compare_mysql_cmd "select-4" "SHOW TABLES;" "-h $cluster-proxysql -uoperator -p'$newpass'"

newpass=$(getSecretData "my-cluster-secrets-2" "root")
desc 'test new users sync'
run_mysql \
	"CREATE USER 'testsync'@'%' IDENTIFIED BY '$newpass';" \
	"-h $cluster-pxc -uroot -p'$newpass'"
sleep 40
compare_mysql_cmd "select-4" "SHOW TABLES;" "-h $cluster-proxysql -utestsync -p'$newpass'"

pass=$(getSecretData "internal-some-name" "operator")
desc 'check secret without operator'
kubectl_bin apply \
	-f "$test_dir/conf/secrets.yml"
sleep 15
compare_mysql_cmd "select-4" "SHOW TABLES;" "-h $cluster-proxysql -uoperator -p'$pass'"

newpass="test-password2"
newpassencrypted=$(echo -n "$newpass" | base64)
apply_config "$test_dir/conf/some-name.yml"
sleep 15
wait_cluster_consistency "$cluster" 3 3
patch_secret "my-cluster-secrets" "monitor" "$newpassencrypted"
sleep 15
wait_cluster_consistency "$cluster" 3 3
compare_mysql_cmd "select-3" "SHOW DATABASES;" "-h $cluster-haproxy -umonitor -p'$newpass'"

destroy "${namespace}"
desc "test passed"
